home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 701-725 / 708 / intuisup / intuisup42.lha / Intuisup / source.lha / Editor / template.c < prev    next >
C/C++ Source or Header  |  1992-04-22  |  22KB  |  764 lines

  1. /* $Revision Header *** Header built automatically - do not edit! ***********
  2.  *
  3.  *    (C) Copyright 1991 by Torsten Jürgeleit
  4.  *
  5.  *    Name .....: template.c
  6.  *    Created ..: Sunday 22-Dec-91 21:23:14
  7.  *    Revision .: 2
  8.  *
  9.  *    Date        Author                 Comment
  10.  *    =========   ====================   ====================
  11.  *    22-Apr-91   Torsten Jürgeleit      changed get_template_by_xxx to
  12.  *                                         select_template_by_xxx
  13.  *    31-Dec-91   Torsten Jürgeleit      new font management
  14.  *    22-Dec-91   Torsten Jürgeleit      Created this file!
  15.  *
  16.  ****************************************************************************
  17.  *
  18.  *    Template part
  19.  *
  20.  * $Revision Header ********************************************************/
  21.  
  22.     /* Includes */
  23.  
  24. #include "includes.h"
  25. #include "defines.h"
  26. #include "imports.h"
  27. #include "protos.h"
  28.  
  29.     /* Select template by given ordinal number from list */
  30.  
  31.    struct Template *
  32. select_template_by_num(LONG num)
  33. {
  34.    struct Template  *tp;
  35.  
  36.    for (tp = get_head((struct List *)&template_list.tl_Templates); tp;
  37.                           tp = get_succ(&tp->tp_Node)) {
  38.       if (!num--) {
  39.      CopyMem((BYTE *)&tp->tp_Box, (BYTE *)¤t_box, (LONG)
  40.                             sizeof(struct Box));
  41.      break;
  42.       }
  43.    }
  44.    selected_template = tp;
  45.    return(tp);
  46. }
  47.     /* Select template by given mouse pos from list */
  48.  
  49.    struct Template *
  50. select_template_by_pos(SHORT x, SHORT y)
  51. {
  52.    struct Template  *tp;
  53.  
  54.    if (tp = find_template_by_pos(x, y)) {
  55.       CopyMem((BYTE *)&tp->tp_Box, (BYTE *)¤t_box, (LONG)
  56.                             sizeof(struct Box));
  57.    }
  58.    selected_template = tp;
  59.    return(tp);
  60. }
  61.     /* Find template by given mouse pos from list */
  62.  
  63.    struct Template *
  64. find_template_by_pos(SHORT x, SHORT y)
  65. {
  66.    struct Template  *tp;
  67.    struct Box       *box;
  68.  
  69.    /* First check info template */
  70.    if (info_displayed == TRUE) {
  71.       tp  = info_template;
  72.       box = &tp->tp_Box;
  73.       if (x >= box->bo_X1 && x <= box->bo_X2 && y >= box->bo_Y1 && y <=
  74.                                    box->bo_Y2) {
  75.      return(tp);
  76.       }
  77.    }
  78.  
  79.    /* Now check templates in list (from last to first) */
  80.    for (tp = get_tail((struct List *)&template_list.tl_Templates); tp;
  81.                           tp = get_pred(&tp->tp_Node)) {
  82.       box = &tp->tp_Box;
  83.       if (x >= box->bo_X1 && x <= box->bo_X2 && y >= box->bo_Y1 && y <=
  84.                                    box->bo_Y2) {
  85.      return(tp);
  86.       }
  87.    }
  88.    return(NULL);
  89. }
  90.     /* Fix bounds of current template */
  91.  
  92.    VOID
  93. fix_template_bounds(VOID)
  94. {
  95.    struct Box  *box = ¤t_box;
  96.  
  97.    if (box->bo_X1 > box->bo_X2) {
  98.       SHORT temp = box->bo_X2;
  99.  
  100.       box->bo_X2 = box->bo_X1;
  101.       box->bo_X1 = temp;
  102.    }
  103.    if (box->bo_Y1 > box->bo_Y2) {
  104.       SHORT temp = box->bo_Y2;
  105.  
  106.       box->bo_Y2 = box->bo_Y1;
  107.       box->bo_Y1 = temp;
  108.    }
  109.    if (box->bo_X1 < 0) {
  110.       box->bo_X1 = 0;
  111.    }
  112.    if (box->bo_Y1 < 0) {
  113.       box->bo_Y1 = 0;
  114.    }
  115.    if (box->bo_X2 > pwin->Width) {
  116.       box->bo_X2 = pwin->Width;
  117.    }
  118.    if (box->bo_Y2 > pwin->Height) {
  119.       box->bo_Y2 = pwin->Height;
  120.    }
  121. }
  122.     /* Get modify mode from selected position */
  123.  
  124.    USHORT
  125. get_modify_mode(SHORT x, SHORT y)
  126. {
  127.    struct Template  *tp = selected_template;
  128.    struct Box       *box = &tp->tp_Box;
  129.    UBYTE  type = tp->tp_Type;
  130.    USHORT part_width  = (box->bo_X2 - box->bo_X1) / 8,
  131.       part_height = (box->bo_Y2 - box->bo_Y1) / 4,
  132.       modify_mode = MODIFY_MODE_MOVE;
  133.  
  134.    if (type != TEMPLATE_TYPE_TEXT && type != TEMPLATE_TYPE_CHECK &&
  135.                          type != TEMPLATE_TYPE_MX) {
  136.       if (x >= (box->bo_X2 - part_width) && x <= box->bo_X2 &&
  137.                y >= (box->bo_Y2 - part_height) && y <= box->bo_Y2) {
  138.      modify_mode = MODIFY_MODE_RESIZE;
  139.       }
  140.    }
  141.    return(modify_mode);
  142. }
  143.     /* Create new template and add it to template list */
  144.  
  145.    struct Template *
  146. create_template(struct TemplateList  *tl)
  147. {
  148.    struct Template  *tp;
  149.    SHORT status = EDITOR_STATUS_NORMAL;
  150.  
  151.    if (!(tp = AllocMem((LONG)sizeof(struct Template),
  152.                      (LONG)MEMF_PUBLIC | MEMF_CLEAR))) {
  153.       status = EDITOR_ERROR_OUT_OF_MEM;
  154.    } else {
  155.  
  156.       /* Init template */
  157.       tp->tp_Node.ln_Name = &tp->tp_TemplateName[0];
  158.       tp->tp_Type         = template_type;
  159.       CopyMem((BYTE *)¤t_box, (BYTE *)&tp->tp_Box, (LONG)
  160.                             sizeof(struct Box));
  161.       NewList(&tp->tp_TextList);
  162.       if ((status = init_default_template_data(tl, tp, FALSE)) !=
  163.                              EDITOR_STATUS_NORMAL) {
  164.      free_template(tl, tp);
  165.      tp = NULL;
  166.       } else {
  167.  
  168.      /* Add new template to list and refresh list view */
  169.      add_template_to_list(tl, tp, TRUE);
  170.      ISetGadgetAttributes(egl, EDITOR_GADGET_TEMPLATES, 0L, 0L,
  171.            USE_CURRENT_VALUE, USE_CURRENT_VALUE, &tl->tl_Templates);
  172.       }
  173.    }
  174.    show_error(status);
  175.    return(tp);
  176. }
  177.     /* Add template to list */
  178.  
  179.    VOID
  180. add_template_to_list(struct TemplateList  *tl, struct Template  *tp,
  181.                               BOOL default_name)
  182. {
  183.    struct List  *list = (struct List *)&tl->tl_Templates;
  184.    USHORT num, pos;
  185.  
  186.    /* Get group data */
  187.    switch (TEMPLATE_GROUP(tp)) {
  188.       case TEMPLATE_GROUP_BORDER :
  189.      num = ++tl->tl_BorderTemplates;
  190.      pos = num - 1;
  191.      break;
  192.  
  193.       case TEMPLATE_GROUP_TEXT :
  194.      num = ++tl->tl_TextTemplates;
  195.      pos = tl->tl_BorderTemplates + num - 1;
  196.      break;
  197.  
  198.       case TEMPLATE_GROUP_GADGET :
  199.      num = ++tl->tl_GadgetTemplates;
  200.      pos = tl->tl_BorderTemplates + tl->tl_TextTemplates + num - 1;
  201.      break;
  202.    }
  203.  
  204.    /* Init template and insert it into template list */
  205.    tp->tp_GroupEntryNum = num;
  206.    if (default_name == TRUE) {
  207.       build_default_template_name(tl, tp);
  208.    }
  209.    Insert(list, &tp->tp_Node, (pos ? get_node(list, pos - 1) : NULL));
  210. }
  211.     /* Build default template name */
  212.  
  213.    VOID
  214. build_default_template_name(struct TemplateList  *tl, struct Template  *tp)
  215. {
  216.    BYTE *fmt;
  217.  
  218.    switch (TEMPLATE_GROUP(tp)) {
  219.       case TEMPLATE_GROUP_BORDER :
  220.      fmt = "BORDER%d";
  221.      break;
  222.  
  223.       case TEMPLATE_GROUP_TEXT :
  224.      fmt = "TEXT%d";
  225.      break;
  226.  
  227.       case TEMPLATE_GROUP_GADGET :
  228.      fmt = "GADGET%d";
  229.      break;
  230.    }
  231.    SPrintf(&tp->tp_TemplateName[0], fmt, tp->tp_GroupEntryNum);
  232.    tp->tp_Flags = TEMPLATE_FLAG_DEFAULT_NAME;
  233. }
  234.     /* Init default template data */
  235.  
  236.    SHORT
  237. init_default_template_data(struct TemplateList  *tl, struct Template  *tp,
  238.                               BOOL default_name)
  239. {
  240.    struct Box         *box = &tp->tp_Box;
  241.    struct BorderData  *bd;
  242.    struct TextData    *td;
  243.    struct GadgetData  *gd;
  244.    USHORT width = box->bo_X2 - box->bo_X1 + 1,
  245.       height = box->bo_Y2 - box->bo_Y1 + 1;
  246.    SHORT  status = EDITOR_STATUS_NORMAL;
  247.  
  248.    /* Init default template name */
  249.    if (default_name == TRUE) {
  250.       build_default_template_name(tl, tp);
  251.    }
  252.  
  253.    /* Init default template data */
  254.    switch (TEMPLATE_GROUP(tp)) {
  255.       case TEMPLATE_GROUP_BORDER :
  256.      bd              = &tp->tp_Data.tp_BorderData;
  257.      bd->bd_Type     = BORDER_DATA_TYPE_BOX2_IN;
  258.      bd->bd_LeftEdge = box->bo_X1;
  259.      bd->bd_TopEdge  = box->bo_Y1;
  260.      bd->bd_Width    = width;
  261.      bd->bd_Height   = height;
  262.  
  263.      /* Mark end of border data */
  264.      (bd + 1)->bd_Type = INTUISUP_DATA_END;
  265.          break;
  266.  
  267.       case TEMPLATE_GROUP_TEXT :
  268.      td              = &tp->tp_Data.tp_TextData;
  269.      td->td_Type     = TEXT_DATA_TYPE_TEXT;
  270.      td->td_Flags    = 0;
  271.      td->td_LeftEdge = box->bo_X1;
  272.      td->td_TopEdge  = box->bo_Y1;
  273.      if (!(td->td_TextAttr = open_template_font_by_attributes(tl,
  274.                   DEFAULT_FONT_NAME, DEFAULT_FONT_YSIZE))) {
  275.         status = EDITOR_ERROR_INVALID_FONT;
  276.      } else {
  277.         if ((status = duplicate_string("Text", &td->td_Text)) ==
  278.                              EDITOR_STATUS_NORMAL) {
  279.            /* Calc size of text for template box */
  280.            box        = &tp->tp_Box;
  281.            box->bo_X2 = box->bo_X1 + IPrintText(pri, pwin, td->td_Text,
  282.                    td->td_LeftEdge, td->td_TopEdge, td->td_Type,
  283.                   TEXT_DATA_FLAG_NO_PRINT, td->td_TextAttr) - 1;
  284.            box->bo_Y2 = box->bo_Y1 + td->td_TextAttr->ta_YSize - 1;
  285.         }
  286.  
  287.         /* Mark end of text data */
  288.         (td + 1)->td_Type = INTUISUP_DATA_END;
  289.      }
  290.      break;
  291.  
  292.       case TEMPLATE_GROUP_GADGET :
  293.      gd              = &tp->tp_Data.tp_GadgetData;
  294.      gd->gd_Type     = tp->tp_Type - FIRST_GADGET_TEMPLATE_TYPE + 1;
  295.      gd->gd_Flags    = 0;
  296.      gd->gd_LeftEdge = box->bo_X1;
  297.      gd->gd_TopEdge  = box->bo_Y1;
  298.      gd->gd_Width    = width;
  299.      gd->gd_Height   = height;
  300.      gd->gd_Text     = NULL;
  301.      if (!(gd->gd_TextAttr = open_template_font_by_attributes(tl,
  302.                   DEFAULT_FONT_NAME, DEFAULT_FONT_YSIZE))) {
  303.         status = EDITOR_ERROR_INVALID_FONT;
  304.      } else {
  305.         switch (gd->gd_Type) {
  306.            case GADGET_DATA_TYPE_BUTTON :
  307.           status = duplicate_string("Button", &gd->gd_Text);
  308.           break;
  309.  
  310.            case GADGET_DATA_TYPE_CHECK :
  311.           gd->gd_SpecialData.gd_CheckData.gd_CheckSelected = 1;
  312.           break;
  313.  
  314.            case GADGET_DATA_TYPE_MX :
  315.           gd->gd_Flags                                 |= GADGET_DATA_FLAG_TEXT_LEFT;
  316.           gd->gd_SpecialData.gd_MXData.gd_MXSpacing     = 1;
  317.           gd->gd_SpecialData.gd_MXData.gd_MXActiveEntry = 0;
  318.           if ((status = build_template_text_list(tp,
  319.                           &default_mx_text_array[0])) ==
  320.                              EDITOR_STATUS_NORMAL) {
  321.              status = build_template_text_array(tp);
  322.           }
  323.           break;
  324.  
  325.            case GADGET_DATA_TYPE_STRING :
  326.           gd->gd_SpecialData.gd_InputData.gd_InputLen          = 10;
  327.           gd->gd_SpecialData.gd_InputData.gd_InputActivateNext = 0;
  328.           gd->gd_SpecialData.gd_InputData.gd_InputActivatePrev = 0;
  329.           status = duplicate_string("String",
  330.               &gd->gd_SpecialData.gd_InputData.gd_InputDefault);
  331.           break;
  332.  
  333.            case GADGET_DATA_TYPE_INTEGER :
  334.           gd->gd_SpecialData.gd_InputData.gd_InputLen          = 10;
  335.           gd->gd_SpecialData.gd_InputData.gd_InputActivateNext = 0;
  336.           gd->gd_SpecialData.gd_InputData.gd_InputActivatePrev = 0;
  337.           gd->gd_SpecialData.gd_InputData.gd_InputDefault      = (BYTE *)123;
  338.           break;
  339.  
  340.            case GADGET_DATA_TYPE_SLIDER :
  341.           if (width / 2 < height) {
  342.              gd->gd_Flags = GADGET_DATA_FLAG_ORIENTATION_VERT;
  343.           }
  344.           gd->gd_SpecialData.gd_SliderData.gd_SliderMin   = 0;
  345.           gd->gd_SpecialData.gd_SliderData.gd_SliderMax   = 10;
  346.           gd->gd_SpecialData.gd_SliderData.gd_SliderLevel = 5;
  347.           break;
  348.  
  349.            case GADGET_DATA_TYPE_SCROLLER :
  350.           if (width / 2 < height) {
  351.              gd->gd_Flags = GADGET_DATA_FLAG_ORIENTATION_VERT;
  352.           }
  353.           gd->gd_SpecialData.gd_ScrollerData.gd_ScrollerVisible = 2;
  354.           gd->gd_SpecialData.gd_ScrollerData.gd_ScrollerTotal   = 10;
  355.           gd->gd_SpecialData.gd_ScrollerData.gd_ScrollerTop     = 5;
  356.           break;
  357.  
  358.            case GADGET_DATA_TYPE_CYCLE :
  359.           gd->gd_SpecialData.gd_CycleData.gd_CycleActive = 0;
  360.           if ((status = build_template_text_list(tp,
  361.                        &default_cycle_text_array[0])) ==
  362.                              EDITOR_STATUS_NORMAL) {
  363.              status = build_template_text_array(tp);
  364.           }
  365.           break;
  366.  
  367.            case GADGET_DATA_TYPE_COUNT :
  368.           gd->gd_SpecialData.gd_CountData.gd_CountMin   = 10;
  369.           gd->gd_SpecialData.gd_CountData.gd_CountMax   = 50;
  370.           gd->gd_SpecialData.gd_CountData.gd_CountValue = 30;
  371.           break;
  372.  
  373.            case GADGET_DATA_TYPE_LISTVIEW :
  374.           gd->gd_Flags                                         |= GADGET_DATA_FLAG_TEXT_ABOVE;
  375.           gd->gd_SpecialData.gd_ListViewData.gd_ListViewSpacing = 0;
  376.           gd->gd_SpecialData.gd_ListViewData.gd_ListViewTop     = 0;
  377.           gd->gd_SpecialData.gd_ListViewData.gd_ListViewList    = &tp->tp_TextList;
  378.           status = build_template_text_list(tp,
  379.                        &default_listview_text_array[0]);
  380.           break;
  381.  
  382.            case GADGET_DATA_TYPE_PALETTE :
  383.           if (width / 2 < height) {
  384.              gd->gd_Flags |= GADGET_DATA_FLAG_PALETTE_INDICATOR_TOP;
  385.           }
  386.           gd->gd_Flags                                           |= GADGET_DATA_FLAG_TEXT_ABOVE;
  387.           gd->gd_SpecialData.gd_PaletteData.gd_PaletteDepth       = 2;
  388.           gd->gd_SpecialData.gd_PaletteData.gd_PaletteColorOffset = 0;
  389.           gd->gd_SpecialData.gd_PaletteData.gd_PaletteActiveColor = 2;
  390.           break;
  391.         }
  392.  
  393.         /* Mark end of gadget data */
  394.         (gd + 1)->gd_Type = INTUISUP_DATA_END;
  395.      }
  396.      break;
  397.    }
  398.    return(status);
  399. }
  400.     /* Clone template and optional add it to template list */
  401.  
  402.    struct Template *
  403. clone_template(struct TemplateList  *tl, struct Template  *old_tp,
  404.                                 BOOL full_clone)
  405. {
  406.    struct Template  *new_tp;
  407.    SHORT status = EDITOR_STATUS_NORMAL;
  408.  
  409.    if (!(new_tp = AllocMem((LONG)sizeof(struct Template),
  410.                      (LONG)MEMF_PUBLIC | MEMF_CLEAR))) {
  411.       status = EDITOR_ERROR_OUT_OF_MEM;
  412.    } else {
  413.  
  414.       /* Init template */
  415.       CopyMem((BYTE *)old_tp, (BYTE *)new_tp, (LONG)sizeof(struct Template));
  416.       new_tp->tp_Node.ln_Name = &new_tp->tp_TemplateName[0];
  417.       NewList(&new_tp->tp_TextList);
  418.       if (full_clone == FALSE) {
  419.      CopyMem((BYTE *)¤t_box, (BYTE *)&new_tp->tp_Box, (LONG)
  420.                             sizeof(struct Box));
  421.       }
  422.       if ((status = clone_template_data(tl, old_tp, new_tp)) !=
  423.                              EDITOR_STATUS_NORMAL) {
  424.      free_template(tl, new_tp);
  425.      new_tp = NULL;
  426.       } else {
  427.      if (full_clone == FALSE) {
  428.  
  429.         /* Add new template to list and refresh list view */
  430.         add_template_to_list(tl, new_tp, TRUE);
  431.         ISetGadgetAttributes(egl, EDITOR_GADGET_TEMPLATES, 0L, 0L,
  432.            USE_CURRENT_VALUE, USE_CURRENT_VALUE, &tl->tl_Templates);
  433.      }
  434.       }
  435.    }
  436.    show_error(status);
  437.    return(new_tp);
  438. }
  439.     /* Clone template data */
  440.  
  441.    STATIC SHORT
  442. clone_template_data(struct TemplateList  *tl, struct Template  *old_tp,
  443.                            struct Template  *new_tp)
  444. {
  445.    struct BorderData  *new_bd;
  446.    struct TextData    *old_td, *new_td;
  447.    struct GadgetData  *old_gd, *new_gd;
  448.    struct Box         *box = &new_tp->tp_Box;
  449.    SHORT status = EDITOR_STATUS_NORMAL;
  450.  
  451.    /* Clear data pointers */
  452.    switch (TEMPLATE_GROUP(new_tp)) {
  453.       case TEMPLATE_GROUP_BORDER :
  454.      new_bd = &new_tp->tp_Data.tp_BorderData;
  455.          break;
  456.  
  457.       case TEMPLATE_GROUP_TEXT :
  458.      old_td = &old_tp->tp_Data.tp_TextData;
  459.      new_td = &new_tp->tp_Data.tp_TextData;
  460.      if (new_td->td_Type == TEXT_DATA_TYPE_TEXT) {
  461.         new_td->td_Text = NULL;
  462.      }
  463.      new_td->td_TextAttr = NULL;
  464.      break;
  465.  
  466.       case TEMPLATE_GROUP_GADGET :
  467.      old_gd              = &old_tp->tp_Data.tp_GadgetData;
  468.      new_gd              = &new_tp->tp_Data.tp_GadgetData;
  469.      new_gd->gd_Text     = NULL;
  470.      new_gd->gd_TextAttr = NULL;
  471.      switch (new_gd->gd_Type) {
  472.         case GADGET_DATA_TYPE_BUTTON :
  473.         case GADGET_DATA_TYPE_CHECK :
  474.         case GADGET_DATA_TYPE_INTEGER :
  475.         case GADGET_DATA_TYPE_SLIDER :
  476.         case GADGET_DATA_TYPE_SCROLLER :
  477.         case GADGET_DATA_TYPE_COUNT :
  478.         case GADGET_DATA_TYPE_PALETTE :
  479.            break;
  480.  
  481.         case GADGET_DATA_TYPE_MX :
  482.            new_gd->gd_SpecialData.gd_MXData.gd_MXTextArray = NULL;
  483.            break;
  484.  
  485.         case GADGET_DATA_TYPE_CYCLE :
  486.            new_gd->gd_SpecialData.gd_CycleData.gd_CycleTextArray = NULL;
  487.            break;
  488.  
  489.         case GADGET_DATA_TYPE_STRING :
  490.            new_gd->gd_SpecialData.gd_InputData.gd_InputDefault = NULL;
  491.            break;
  492.  
  493.         case GADGET_DATA_TYPE_LISTVIEW :
  494.            new_gd->gd_SpecialData.gd_ListViewData.gd_ListViewList = &new_tp->tp_TextList;
  495.            break;
  496.      }
  497.      break;
  498.    }
  499.  
  500.    /* Allocate new data */
  501.    switch (TEMPLATE_GROUP(new_tp)) {
  502.       case TEMPLATE_GROUP_BORDER :
  503.      new_bd->bd_LeftEdge = box->bo_X1;
  504.      new_bd->bd_TopEdge  = box->bo_Y1;
  505.      break;
  506.  
  507.       case TEMPLATE_GROUP_TEXT :
  508.      new_td->td_LeftEdge = box->bo_X1;
  509.      new_td->td_TopEdge  = box->bo_Y1;
  510.      if (!(new_td->td_TextAttr = open_template_font_by_attributes(tl,
  511.                        (BYTE *)old_td->td_TextAttr->ta_Name,
  512.                       old_td->td_TextAttr->ta_YSize))) {
  513.         status = EDITOR_ERROR_INVALID_FONT;
  514.      } else {
  515.         if (new_td->td_Type == TEXT_DATA_TYPE_TEXT) {
  516.            status = duplicate_string(old_td->td_Text, &new_td->td_Text);
  517.         }
  518.      }
  519.      break;
  520.  
  521.       case TEMPLATE_GROUP_GADGET :
  522.      new_gd->gd_LeftEdge = box->bo_X1;
  523.      new_gd->gd_TopEdge  = box->bo_Y1;
  524.      if (!(new_gd->gd_TextAttr = open_template_font_by_attributes(tl,
  525.                        (BYTE *)old_gd->gd_TextAttr->ta_Name,
  526.                       old_gd->gd_TextAttr->ta_YSize))) {
  527.         status = EDITOR_ERROR_INVALID_FONT;
  528.      } else {
  529.         if ((status = duplicate_string(old_gd->gd_Text,
  530.                    &new_gd->gd_Text)) == EDITOR_STATUS_NORMAL) {
  531.            switch (new_gd->gd_Type) {
  532.           case GADGET_DATA_TYPE_BUTTON :
  533.           case GADGET_DATA_TYPE_CHECK :
  534.           case GADGET_DATA_TYPE_INTEGER :
  535.           case GADGET_DATA_TYPE_SLIDER :
  536.           case GADGET_DATA_TYPE_SCROLLER :
  537.           case GADGET_DATA_TYPE_COUNT :
  538.           case GADGET_DATA_TYPE_PALETTE :
  539.              break;
  540.  
  541.           case GADGET_DATA_TYPE_MX :
  542.           case GADGET_DATA_TYPE_CYCLE :
  543.              if ((status = duplicate_text_list(old_tp, new_tp)) ==
  544.                              EDITOR_STATUS_NORMAL) {
  545.             status = build_template_text_array(new_tp);
  546.              }
  547.              break;
  548.  
  549.           case GADGET_DATA_TYPE_STRING :
  550.              status = duplicate_string(old_gd->gd_SpecialData.gd_InputData.gd_InputDefault, &new_gd->gd_SpecialData.gd_InputData.gd_InputDefault);
  551.              break;
  552.  
  553.           case GADGET_DATA_TYPE_LISTVIEW :
  554.              status = duplicate_text_list(old_tp, new_tp);
  555.              break;
  556.            }
  557.         }
  558.      }
  559.      break;
  560.    }
  561.    return(status);
  562. }
  563.     /* Display template */
  564.  
  565.    VOID
  566. display_template(struct Template  *tp)
  567. {
  568.    struct TextData    *td;
  569.    struct GadgetData  *gd;
  570.    APTR gl;
  571.  
  572.    switch (TEMPLATE_GROUP(tp)) {
  573.       case TEMPLATE_GROUP_BORDER :
  574.      IDisplayBorders(pri, pwin, &tp->tp_Data.tp_BorderData, 0, 0);
  575.      break;
  576.  
  577.       case TEMPLATE_GROUP_TEXT :
  578.      td = &tp->tp_Data.tp_TextData;
  579.      IDisplayTexts(pri, pwin, td, 0, 0, NULL);
  580.      break;
  581.  
  582.       case TEMPLATE_GROUP_GADGET :
  583.      gd = &tp->tp_Data.tp_GadgetData;
  584.      if (!(gl = ICreateGadgets(pri, gd, 0, 0, NULL))) {
  585.         show_error(EDITOR_ERROR_OUT_OF_MEM);
  586.      } else {
  587.         USHORT *dim = (USHORT *)(IGadgetAddress(gl, 0) + 1);
  588.  
  589.         /* Update template box with gadget size */
  590.         IDisplayGadgets(pwin, gl);
  591.         switch (gd->gd_Type) {
  592.            case GADGET_DATA_TYPE_CHECK :
  593.            case GADGET_DATA_TYPE_MX :
  594.            case GADGET_DATA_TYPE_PALETTE :
  595.            case GADGET_DATA_TYPE_LISTVIEW :
  596.            case GADGET_DATA_TYPE_STRING :
  597.            case GADGET_DATA_TYPE_INTEGER :
  598.           tp->tp_Box.bo_X2 = tp->tp_Box.bo_X1 + dim[0] - 1;
  599.           tp->tp_Box.bo_Y2 = tp->tp_Box.bo_Y1 + dim[1] - 1;
  600.           break;
  601.         }
  602.         IRemoveGadgets(gl);
  603.         IFreeGadgets(gl);
  604.      }
  605.      break;
  606.    }
  607. }
  608.     /* Refresh all templates */
  609.  
  610.    VOID
  611. refresh_all_templates(VOID)
  612. {
  613.    struct TemplateList  *tl = &template_list;
  614.    struct Template      *tp;
  615.  
  616.    clear_project_window(tl->tl_Flags);
  617.    print_project_window_title();
  618.    if (editor_mode == EDITOR_MODE_USE) {
  619.       IRefreshGadgets(use_gl);
  620.  
  621.       /* Refresh non gadget templates */
  622.       for (tp = get_head((struct List *)&tl->tl_Templates); tp;
  623.                           tp = get_succ(&tp->tp_Node)) {
  624.      if (TEMPLATE_GROUP(tp) != TEMPLATE_GROUP_GADGET) {
  625.         display_template(tp);
  626.      }
  627.       }
  628.    } else {
  629.       for (tp = get_head((struct List *)&tl->tl_Templates); tp;
  630.                           tp = get_succ(&tp->tp_Node)) {
  631.      display_template(tp);
  632.       }
  633.    }
  634. }
  635.     /* Free template list */
  636.  
  637.    VOID
  638. free_template_list(struct TemplateList  *tl)
  639. {
  640.    struct Template  *tp;
  641.    struct List      *list = (struct List *)&tl->tl_Templates;
  642.  
  643.    free_font_list(tl);
  644.    while (tp = (struct Template *)RemHead(list)) {
  645.       switch (TEMPLATE_GROUP(tp)) {
  646.      case TEMPLATE_GROUP_BORDER :
  647.         tl->tl_BorderTemplates--;
  648.         break;
  649.  
  650.      case TEMPLATE_GROUP_TEXT :
  651.         tl->tl_TextTemplates--;
  652.         break;
  653.  
  654.      case TEMPLATE_GROUP_GADGET :
  655.         tl->tl_GadgetTemplates--;
  656.         break;
  657.       }
  658.       free_template(tl, tp);
  659.    }
  660.    tl->tl_Flags &= ~TEMPLATE_LIST_FLAG_CHANGED;
  661.    MWCheck();
  662. }
  663.     /* Free template */
  664.  
  665.    VOID
  666. free_template(struct TemplateList  *tl, struct Template  *tp)
  667. {
  668.    if (tl && tp) {
  669.       free_template_data(tl, tp);
  670.       FreeMem(tp, (LONG)sizeof(struct Template));
  671.    }
  672. }
  673.     /* Free template data */
  674.  
  675.    VOID
  676. free_template_data(struct TemplateList  *tl, struct Template  *tp)
  677. {
  678.    struct TextData    *td;
  679.    struct GadgetData  *gd;
  680.  
  681.    switch (TEMPLATE_GROUP(tp)) {
  682.       case TEMPLATE_GROUP_BORDER :
  683.      break;
  684.  
  685.       case TEMPLATE_GROUP_TEXT :
  686.      td = &tp->tp_Data.tp_TextData;
  687.      close_template_font(tl, td->td_TextAttr);
  688.      if (td->td_Type == TEXT_DATA_TYPE_TEXT) {
  689.         DosFreeMem(td->td_Text);
  690.      }
  691.      td->td_Text = NULL;
  692.      break;
  693.  
  694.       case TEMPLATE_GROUP_GADGET :
  695.      gd = &tp->tp_Data.tp_GadgetData;
  696.      close_template_font(tl, gd->gd_TextAttr);
  697.      DosFreeMem(gd->gd_Text);
  698.      gd->gd_Text = NULL;
  699.      switch (gd->gd_Type) {
  700.         case GADGET_DATA_TYPE_BUTTON :
  701.         case GADGET_DATA_TYPE_CHECK :
  702.         case GADGET_DATA_TYPE_INTEGER :
  703.         case GADGET_DATA_TYPE_SLIDER :
  704.         case GADGET_DATA_TYPE_SCROLLER :
  705.         case GADGET_DATA_TYPE_COUNT :
  706.         case GADGET_DATA_TYPE_PALETTE :
  707.            break;
  708.  
  709.         case GADGET_DATA_TYPE_MX :
  710.         case GADGET_DATA_TYPE_CYCLE :
  711.            free_template_text_array(tp);
  712.         case GADGET_DATA_TYPE_LISTVIEW :
  713.            free_template_text_list(tp);
  714.            break;
  715.  
  716.         case GADGET_DATA_TYPE_STRING :
  717.            DosFreeMem(gd->gd_SpecialData.gd_InputData.gd_InputDefault);
  718.            break;
  719.      }
  720.      break;
  721.    }
  722. }
  723.     /* Delete template */
  724.  
  725.    VOID
  726. delete_template(struct Template  *tp)
  727. {
  728.    struct TemplateList  *tl = &template_list;
  729.    struct Template      *succ_tp;
  730.    UBYTE group = TEMPLATE_GROUP(tp);
  731.  
  732.    /* Remove template from list, decrement counters and free template */
  733.    succ_tp = get_succ(&tp->tp_Node);
  734.    Remove(&tp->tp_Node);
  735.    switch (group) {
  736.       case TEMPLATE_GROUP_BORDER :
  737.      tl->tl_BorderTemplates--;
  738.      break;
  739.  
  740.       case TEMPLATE_GROUP_TEXT :
  741.      tl->tl_TextTemplates--;
  742.      break;
  743.  
  744.       case TEMPLATE_GROUP_GADGET :
  745.      tl->tl_GadgetTemplates--;
  746.      break;
  747.    }
  748.    free_template(tl, tp);
  749.  
  750.    /* Update default template names and refresh template list */
  751.    for (tp = succ_tp; tp; tp = get_succ(&tp->tp_Node)) {
  752.       if (TEMPLATE_GROUP(tp) == group) {
  753.      tp->tp_GroupEntryNum--;
  754.      if (tp->tp_Flags & TEMPLATE_FLAG_DEFAULT_NAME) {
  755.         build_default_template_name(tl, tp);
  756.      }
  757.       }
  758.    }
  759.    ISetGadgetAttributes(egl, EDITOR_GADGET_TEMPLATES, 0L, 0L,
  760.            USE_CURRENT_VALUE, USE_CURRENT_VALUE, &tl->tl_Templates);
  761.    refresh_all_templates();
  762.    tl->tl_Flags |= TEMPLATE_LIST_FLAG_CHANGED;
  763. }
  764.